package cn.tannn.tgateway.plugin;

import cn.tannn.tgateway.AbstractGatewayPlugin;
import cn.tannn.tgateway.GatewayPluginChain;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

/**
 * 测试 plugin 1
 *
 * @author <a href="https://t.tannn.cn/">tan</a>
 * @date 2024/5/30 下午4:06
 */
@Component("tanRpc")
public class TanRpcPlugin extends AbstractGatewayPlugin {

    /**
     * plugin name
     */
    public static final String NAME = "trpc";
    /**
     * request prefix
     */
    private String prefix = GATEWAY_PREFIX + "/" + NAME + "/";


    @Override
    public boolean doSupport(ServerWebExchange exchange) {
        return exchange.getRequest().getPath().value().startsWith(prefix);
    }

    @Override
    public Mono<Void> doHandle(ServerWebExchange exchange, GatewayPluginChain chain) {
        String url = "http://localhost:8081/trpc";
        String service = exchange.getRequest().getPath().value().substring(prefix.length());

        // 拿到请求的报文
        Flux<DataBuffer> requestBody = exchange.getRequest().getBody();

        // 通过webclient发送post请求
        WebClient client = WebClient.create(url);
        Mono<ResponseEntity<String>> entity = client.post()
                .header("Content-Type", "application/json")
                .body(requestBody, DataBuffer.class).retrieve().toEntity(String.class);

        // 通过entity获取响应报文
        Mono<String> body = entity.mapNotNull(ResponseEntity::getBody);
        // 7. 组装响应报文
        exchange.getResponse().getHeaders().add("Content-Type", "application/json");
        exchange.getResponse().getHeaders().add("tan.gw.version", "v1.0.0");
        exchange.getResponse().getHeaders().add("tan.gw.plugin", getName());
        return body.flatMap(x -> exchange.getResponse()
                        .writeWith(Mono.just(exchange.getResponse().bufferFactory().wrap(x.getBytes()))))
                // 继续执行 chain 逻辑，不打断 plugin链
                .then(chain.handle(exchange));
    }

    @Override
    public String getName() {
        return NAME;
    }
}
